package com.xscha.soyue.common.doc.config;

import com.xscha.soyue.common.doc.properties.SpringDocProperties;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * Swagger文档配置
 *
 * @author Vondser
 * @version 3.5.0
 * @date 2024/02/29 12:12
 */
@AutoConfiguration
@EnableConfigurationProperties(SpringDocProperties.class)
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
public class SwaggerAutoConfiguration {

	@Bean
	public OpenAPI springOpenAPI(SpringDocProperties springDocProperties) {
		return new OpenAPI().info(apiInfo(springDocProperties)).components(components());
	}

	private Info apiInfo(SpringDocProperties springDocProperties) {
		return new Info().title(springDocProperties.getInfo().getTitle())
			.description(springDocProperties.getInfo().getDescription())
			.license(license(springDocProperties))
			.contact(contact(springDocProperties))
			.termsOfService(springDocProperties.getInfo().getTermsOfService())
			.version(springDocProperties.getInfo().getVersion());
	}

	private License license(SpringDocProperties springDocProperties) {
		return new License().name(springDocProperties.getInfo().getLicense().getName())
			.url(springDocProperties.getInfo().getLicense().getUrl());
	}

	private Contact contact(SpringDocProperties springDocProperties) {
		return new Contact().name(springDocProperties.getInfo().getContact().getName())
			.url(springDocProperties.getInfo().getContact().getName())
			.email(springDocProperties.getInfo().getContact().getEmail());
	}

	/**
	 * 默认的全局鉴权策略
	 */
	private Components components() {
		return new Components().addSecuritySchemes("token",
				new SecurityScheme().type(SecurityScheme.Type.APIKEY)
					.in(SecurityScheme.In.HEADER)
					.name("Authorization")
					.bearerFormat("JWT"));
	}

	@Bean
	public GroupedOpenApi usersGroup() {
		return GroupedOpenApi.builder().group("all").addOperationCustomizer((operation, handlerMethod) -> {
			operation.addSecurityItem(new SecurityRequirement().addList("token"));
			return operation;
		}).build();
	}

}
